Current File : /var/www/e360ban/wp-content/plugins/wp-views/embedded/inc/wpv-archive-loop.php
<?php

/**
 * Hook into the template redirect and see if it's an archive loop.
 *
 * Use the select page (that contains a View) to display the loop items.
 *
 * @todo this needs to happen waaay earlier so we can catch pre_get_posts
 *
 * @since unknown
 */

use OTGS\Toolset\Views\Models\ContentTemplate\UsagePostType;

/**
 * wpv_force_wordpress_archive
 *
 * Applies the wpv_filter_force_wordpress_archive filter to the WPA ID to be displayed
 *
 * @param $wpa_to_apply (integer) the ID of the WPA we want to overwrite
 * @param $wpa_slug (string) [view_cpt_{post_slug}|view_taxonomy_loop_{taxonomy_slug}|view_home-blog-page|view_search-page
 *	 |view_author-page|view_year-page|view_month-page|view_day-page] the kind of WPA being processed
 *
 * @return (int) the ID of the WPA to apply_filters
 *
 * @since 1.6.0
 */
function wpv_force_wordpress_archive( $wpa_to_apply, $wpa_slug ) {

	/**
	 * Filter wpv_filter_force_wordpress_archive
	 *
	 * @param $wpa_to_apply (integer) the ID of the WPA we want to overwrite
	 * @param $wpa_slug (string) [view_cpt_{post_slug}|view_taxonomy_loop_{taxonomy_slug}|view_home-blog-page
	 *	 |view_search-page|view_author-page|view_year-page|view_month-page|view_day-page] the kind of WPA being processed.
	 *
	 * @return (int) the ID of the WPA to apply
	 *
	 * @since 1.6.0
	 * @since 2.3.0 Added a duplicated wpv_filter_wpv_override_wordpress_archive for better naming
	 */
	$wpa_to_apply = apply_filters( 'wpv_filter_force_wordpress_archive', $wpa_to_apply, $wpa_slug );
	$wpa_to_apply = apply_filters( 'wpv_filter_wpv_override_wordpress_archive', $wpa_to_apply, $wpa_slug );
	return $wpa_to_apply;
}


/**
* WPV_WordPress_Archive_Frontend
*
* @todo comment properly
* @todo declare fields that are being declared dynamically in the code
*
* @since 2.00	Renamed to WPV_WordPress_Archive_Frontend from WP_Views_archive_loops and transformed into a singleton
*/

class WPV_WordPress_Archive_Frontend {

	const SETTINGS_TAXONOMY_LOOP = 'view_taxonomy_loop_%s';
	const SETTINGS_TAXONOMY_LOOP_OPTION = 'view_taxonomy_option_loop_%s_option_%s';
	const SETTINGS_TAXONOMY_LOOP_OPTION_REGEXP_TEMPLATE = '/view_taxonomy_option_loop_%s_option_(.*)/';

	const CREATE_ARCHIVE_POPUP_TEMPLATE = <<<EOF
<div class="wpv-modal-form">
	<div class="js-wpv-error-container"></div>
	<label for="wpv-new-archive-name">%s</label>
	<input id="wpv-new-archive-name" type="text" value="" class="js-wpv-new-archive-name wpv-new-archive-name" placeholder="%s" name="wpv-new-archive-name">
</div>
EOF;

	const KEY_LOOP_SINGLE_CT_CONDITIONS = 'single_ct_conditions';

	const KEY_LOOP_SINGLE_CT = 'single_ct';

	const KEY_LOOP_ARCHIVE_CT = 'ct';

	/**
	 * @var WPV_WordPress_Archive_Frontend Instance of WPV_WordPress_Archive_Frontend.
	 */
	private static $instance = null;

	/**
	 * @var \Toolset_Post_Type_Repository
	 */
	private $post_type_repository;

	/**
	 * @return WPV_WordPress_Archive_Frontend The instance of WPV_WordPress_Archive_Frontend.
	 */
	public static function get_instance() {
		if( null == WPV_WordPress_Archive_Frontend::$instance ) {
			WPV_WordPress_Archive_Frontend::$instance = new WPV_WordPress_Archive_Frontend();
		}
		return WPV_WordPress_Archive_Frontend::$instance;
	}

	public static function clear_instance() {
		if ( WPV_WordPress_Archive_Frontend::$instance ) {
			WPV_WordPress_Archive_Frontend::$instance = null;
		}
	}

	/**
	 * @param \WPV_Settings|null $wpv_settings - optionally pass a settings instance.
	 * @param \Toolset_Post_Type_Repository|null $post_type_repository - optionally pass a Post Type Repository instance.
	 */
	public function __construct(
		$wpv_settings = null,
		$post_type_repository = null
	) {

		add_action( 'init',					array( $this, 'init' ) );

		// We set the current WPA to use at pre_get_posts with priority 11,
		// since WooCommerce transforms its shop page into the products archive at pre_get_posts:10
		add_action( 'pre_get_posts',		array( $this, 'archive_set' ), 11 );
		add_action( 'pre_get_posts',		array( $this, 'archive_apply_settings' ), 99 );
		add_action( 'template_redirect',	array( $this, 'initialize_archive_loop' ) );
		add_action( 'wp',					array( $this, 'force_disable_404' ), -1 );

		// Fake archive query for AJAX
		add_action( 'pre_get_posts',										array( $this, 'fake_archive_before_set' ), 0 );
		add_action( 'wp_ajax_wpv_get_archive_query_results',				array( $this, 'wpv_get_archive_query_results' ) );
		add_action( 'wp_ajax_nopriv_wpv_get_archive_query_results',			array( $this, 'wpv_get_archive_query_results' ) );

		// Set archive defaults for existing objects
		add_filter( 'wpv_view_settings',									array( $this, 'wpv_view_settings_archive_set_fallbacks' ), 6, 2 );

		add_action( 'wpv_action_apply_archive_query_settings',				array( $this, 'archive_apply_post_type_settings' ), 10, 3 );
		add_action( 'wpv_action_apply_archive_query_settings',				array( $this, 'archive_apply_order_settings' ), 20, 3 );
		add_action( 'wpv_action_apply_archive_query_settings',				array( $this, 'archive_apply_pagination_settings' ), 30, 3 );

		add_action( 'wpv_action_extend_archive_query_for_parametric_and_counters',	array( $this, 'extend_archive_query_for_parametric_and_counters' ), 10, 3 );

		add_filter( 'wpv_filter_wpv_get_dependant_extended_query_args',		array( $this, 'wpv_get_dependant_archive_query_args' ), 10, 3 );

		add_filter( 'wpv_filter_wpv_get_current_archive',					array( $this, 'wpv_get_current_archive' ) );
		add_filter( 'wpv_filter_wpv_get_current_archive_loop',				array( $this, 'wpv_get_current_archive_loop' ) );

		add_filter( 'wpv_filter_wpv_get_archive_unique_hash',				array( $this, 'wpv_get_archive_unique_hash' ) );

		// Extend pagination settings

		add_filter( 'wpv_filter_wpv_get_pagination_settings',				array( $this, 'extend_pagination_settings' ), 20, 2 );
		add_filter( 'wpv_filter_wpv_get_parametric_settings',				array( $this, 'extend_parametric_settings' ), 20, 2 );

		$this->wpa_id				= null;
		$this->wpa_slug				= '';
		$this->wpa_type				= '';
		$this->wpa_name				= '';
		$this->wpa_data				= array();
		$this->wpa_settings			= array();

		$this->query				= null;

		$this->header_started		= false;
		$this->in_head				= false;

		$this->in_the_loop			= false;
		$this->loop_found			= false;

		$this->loop_has_no_posts	= false;

		$this->wpv_settings			= null !== $wpv_settings ? $wpv_settings : WPV_Settings::get_instance();
		$this->post_type_repository = $post_type_repository;

		// Layouts compatibility
		add_action( 'wpv_action_wpv_initialize_wordpress_archive_for_archive_loop',		array( $this, 'wpv_initialize_wordpress_archive_for_archive_loop' ) );
		// General compatibility.
		add_action( 'pre_get_posts', array( $this, 'early_pre_get_posts' ), 9 );
	}

	function __destruct(){

	}

	function init() {
		/*
		DEPRECATED, need some work to delete
		_get_post_type_loops
		*/

		/*
		* ---------------------------------
		* Compatibility
		* ---------------------------------
		*/

		/*
		* WooCommerce
		*
		* Search results on product archive pages with just one result redirect to the product page
		* But if there are no results, the way we fake one dummy post breaks it all
		*
		* @since unknown
		*/

		add_action( 'wpv_action_before_initialize_archive_loop', array( $this, 'wpv_wpa_fix_woocommerce_archives' ), 10, 2 );

	}

	function archive_set( $query ) {
		if (
			! $this->is_frontend()
			|| ! $query->is_main_query()
			|| $query->is_singular
		) {
			return;
		}

		$stored_settings	= $this->wpv_settings;
		$wpa_to_apply		= 0;
		$wpa_slug			= '';

		// See if we have a WPA for the home page
		if ( is_home() ) {
			$wpa_slug = 'view_home-blog-page';
			$this->wpa_type = 'native';
			$this->wpa_name = 'home';
			$this->wpa_data = array();
			if (
				isset( $stored_settings['view_home-blog-page'] )
				&& $stored_settings['view_home-blog-page'] > 0
			) {
				$wpa_to_apply = $stored_settings['view_home-blog-page'];
			}
		}
		// Check if it's a post type archive and if we have a WPA for it
		if ( is_post_type_archive() ) {
			// From $query->is_post_type_archive() using the same logic based on $query->get('post_type')
			// Before 1.7, we checked against $query->get_queried_object()->public and used $query->get_queried_object()->name
			// But sometimes is_post_type_archive() is TRUE and $query->get_queried_object() is not a post type object, but a post object
			// For example, on some scenarios for WooCommerce shop pages
			// In addition, we do not check now whether the post type is public or not: if it wasn't, there would not be a frontend archive for it
			$post_type = $query->get( 'post_type' );
			if ( is_array( $post_type ) ) {
				$post_type = reset( $post_type );
			}
			$wpa_slug = 'view_cpt_' . $post_type;
			$this->wpa_type = 'post_type';
			$this->wpa_name = $post_type;
			$this->wpa_data = array();
			if (
				isset( $stored_settings['view_cpt_' . $post_type] )
				&& $stored_settings['view_cpt_' . $post_type] > 0
			) {
				$wpa_to_apply = $stored_settings['view_cpt_' . $post_type];
			}
		}
		// Check taxonomy loops
		if ( is_archive() ) {
			if (
				is_tax()
				|| is_category()
				|| is_tag()
			) {// Check this condition, maybe against $query->property directly
				$term = $query->get_queried_object();
				if (
					$term
					&& isset( $term->taxonomy )
				) {
					$wpa_slug = sprintf( self::SETTINGS_TAXONOMY_LOOP, $term->taxonomy );
					$wpa_term_slug = sprintf( self::SETTINGS_TAXONOMY_LOOP_OPTION, $term->taxonomy, $term->slug );

					$current_language = apply_filters( 'wpml_current_language', '' );
					$default_language = apply_filters( 'wpml_default_language', '' );
					if ( $current_language !== $default_language ) {
						$translated_term_id = apply_filters( 'wpml_object_id', $term->term_id, $term->taxonomy, true, $default_language );
						do_action( 'wpml_switch_language', $default_language );
						$original_term = get_term( $translated_term_id, $term->taxonomy );
						do_action( 'wpml_switch_language', $current_language );
						if ( false !== $original_term ) {
							$wpa_term_slug = sprintf( self::SETTINGS_TAXONOMY_LOOP_OPTION, $term->taxonomy, $original_term->slug );
						}
					}

					$this->wpa_type = 'taxonomy';
					$this->wpa_name = $term->taxonomy;
					$this->wpa_data = array(
						'taxonomy'		=> $term->taxonomy,
						'term'			=> $term->slug,
						'term_id'		=> $term->term_id
					);

					if (
						isset( $stored_settings[ $wpa_term_slug ] )
						&& $stored_settings[ $wpa_term_slug ] > 0
					) {
						$wpa_to_apply = $stored_settings[ $wpa_term_slug ];
					} elseif (
						isset( $stored_settings[ $wpa_slug ] )
						&& $stored_settings[ $wpa_slug ] > 0
					) {
						$wpa_to_apply = $stored_settings[ $wpa_slug ];
					}
				}
			}
		}
		// Check other archives
		if ( is_search() ) {
			$wpa_slug = 'view_search-page';
			$this->wpa_type = 'native';
			$this->wpa_name = 'search';
			$this->wpa_data = array(
				's'	=> get_query_var( 's' )
			);
			if (
				isset( $stored_settings['view_search-page'] )
				&& (int) $stored_settings['view_search-page'] > 0
			) {
				$wpa_to_apply = $stored_settings['view_search-page'];
			}
		}
		if ( is_author() ) {
			$wpa_slug = 'view_author-page';
			$this->wpa_type = 'native';
			$this->wpa_name = 'author';
			$this->wpa_data = array(
				'author_name' => get_query_var( 'author_name' )
			);
			if (
				isset( $stored_settings['view_author-page'] )
				&& $stored_settings['view_author-page'] > 0
			) {
				$wpa_to_apply = $stored_settings['view_author-page'];
			}
		}
		if ( is_year() ) {
			$wpa_slug = 'view_year-page';
			$this->wpa_type = 'native';
			$this->wpa_name = 'year';
			$this->wpa_data = array(
				'year' => get_query_var( 'year' )
			);
			if (
				isset( $stored_settings['view_year-page'] )
				&& $stored_settings['view_year-page'] > 0
			) {
				$wpa_to_apply = $stored_settings['view_year-page'];
			}
		}
		if ( is_month() ) {
			$wpa_slug = 'view_month-page';
			$this->wpa_type = 'native';
			$this->wpa_name = 'month';
			$this->wpa_data = array(
				'year'		=> get_query_var( 'year' ),
				'monthnum'	=> get_query_var( 'monthnum' )
			);
			if (
				isset( $stored_settings['view_month-page'] )
				&& $stored_settings['view_month-page'] > 0
			) {
				$wpa_to_apply = $stored_settings['view_month-page'];
			}
		}
		if ( is_day() ) {
			$wpa_slug = 'view_day-page';
			$this->wpa_type = 'native';
			$this->wpa_name = 'day';
			$this->wpa_data = array(
				'year'		=> get_query_var( 'year' ),
				'monthnum'	=> get_query_var( 'monthnum' ),
				'day'		=> get_query_var( 'day' )
			);
			if (
				isset( $stored_settings['view_day-page'] )
				&& $stored_settings['view_day-page'] > 0
			) {
				$wpa_to_apply = $stored_settings['view_day-page'];
			}
		}

		$this->wpa_slug	= $wpa_slug;
		$wpa_to_apply	= wpv_force_wordpress_archive( $wpa_to_apply, $wpa_slug );

		if ( ! is_null( $this->wpa_id ) ) {
			// We have a forced WPA to apply, so we used this method to check which archive page we are in
			// This only hapens on Layouts archive cells as we need to initialize a WPA not assigned to a given loop, overriding the Views stored settings
			$wpa_status = get_post_status( $wpa_to_apply );
			// The WPA must be published ( not trashed )
			if ( $wpa_status == 'publish' ) {
				$this->wpa_settings	= apply_filters( 'wpv_filter_wpv_get_view_settings', array(), $this->wpa_id );
				$this->wpa_settings = apply_filters( 'wpv_filter_object_settings_for_fake_url_query_filters', $this->wpa_settings );
			}
		} else if ( $wpa_to_apply > 0 ) {
			// There is a stored WPA to apply
			$wpa_status = get_post_status( $wpa_to_apply );
			// The WPA must be published ( not trashed )
			if ( $wpa_status == 'publish' ) {
				$this->wpa_id		= $wpa_to_apply;
				$this->wpa_settings	= apply_filters( 'wpv_filter_wpv_get_view_settings', array(), $this->wpa_id );
				$this->wpa_settings = apply_filters( 'wpv_filter_object_settings_for_fake_url_query_filters', $this->wpa_settings );
			}
		}

		/**
		 * Fire an action after checkign whether the current archive loop has a WPA assigned.
		 *
		 * @param int|null The assigned WPA ID, null otherwise
		 *
		 * @since 2.6.0
		 */
		do_action( 'wpv_action_after_archive_set', $this->wpa_id );

	}

	/**
	* wpv_view_settings_archive_set_fallbacks
	*
	* Set default values for the settings we add on different tags.
	*
	* @since 2.1
	*/

	function wpv_view_settings_archive_set_fallbacks( $view_settings, $view_id ) {
		if (
			isset( $view_settings['view-query-mode'] )
			&& $view_settings['view-query-mode'] != 'normal'
		) {
			$defaults = array(
				'view_purpose'				=> 'all',
				'sections-show-hide'		=> array(
													'filter-extra-parametric'	=> 'off',
													'filter-extra'				=> 'off',
													'content'					=> 'off',
												),
				'orderby'					=> 'post_date',
				'order'						=> 'DESC',
				'orderby_second'			=> '',
				'order_second'				=> 'DESC',
				'pagination'				=> array(
													'type'						=> 'paged',
													'posts_per_page'			=> 'default',
													'effect'					=> 'fade',
													'duration'					=> 500,
													'manage_history'			=> 'off',
													'tolerance'					=> '',
													'preload_images'			=> true,
													'cache_pages'				=> true,
													'preload_pages'				=> true,
													'pre_reach'					=> 1,
													'spinner'					=> 'builtin',
													'spinner_image'				=> WPV_URL . '/res/img/ajax-loader.gif',
													'spinner_image_uploaded'	=> '',
													'callback_next'				=> '' ,
												),
				'filter_meta_html_state'	=> array(
													'html'				=> 'on',
													'css'				=> 'off',
													'js'				=> 'off',
													'img'				=> 'off'
												),
				'filter_meta_html'			=> "[wpv-filter-start hide=\"false\"]\n[wpv-filter-controls][/wpv-filter-controls]\n[wpv-filter-end]",
				'filter_meta_html_css'		=> '',
				'filter_meta_html_js'		=> '',
			);
			foreach ( $defaults as $default_key => $default_value ) {
				if ( ! isset( $view_settings[ $default_key ] ) ) {
					$view_settings[ $default_key ] = $default_value;
				}
			}
			// We need to enforce the screen options, as we already had one entry for the 'content' section
			if ( 'all' == $view_settings['view_purpose'] ) {
				foreach ( $defaults['sections-show-hide'] as $screen_opt_key => $screen_opt_val ) {
					if ( ! isset( $view_settings['sections-show-hide'][ $screen_opt_key ] ) ) {
						$view_settings['sections-show-hide'][ $screen_opt_key ] = $screen_opt_val;
					}
				}
			}

			if ( defined( 'WPV_BLOCK_PREVIEW_RENDER' ) && isset( $view_settings['orderby'] )
				&& 'rand'
				=== $view_settings['orderby'] ) {
				$view_settings['orderby'] = 'title';
			}
		}
		return $view_settings;
	}

	function archive_apply_settings( $query ) {

		if (
			! $this->is_frontend()
			|| ! $query->is_main_query()
			|| ! $this->wpa_id
		) {
			return;
		}

		/**
		 * Adjust the WordPress Archive settings just before the main WordPress Archive query.
		 *
		 * @param array $wpa_settings
		 * @return $wpa_settings
		 * @since 3.0
		 */
		$wpa_settings = apply_filters( 'wpv_filter_object_settings_for_fake_url_query_filters', $this->wpa_settings );

		/**
		 * Hook for the actions applied to the archive query settings.
		 *
		 * @param $query
		 * @param $wpa_settings
		 * @param $wpa_id
		 */
		do_action( 'wpv_action_apply_archive_query_settings', $query, $wpa_settings, $this->wpa_id );

	}

	/**
	* archive_apply_post_type_settings
	*
	* Apply post types settings for WordPress Archives.
	*
	* Usefull in the blog and other native loops, categories and tags archives, and search result.
	*
	* @note Post type order seems irrelevant
	*
	* @since 2.1
	*/

	function archive_apply_post_type_settings( $query, $archive_settings, $archive_id ) {
		/*
		if ( $query->get( 'wpv_archive_loop_cell' ) ) {
			// When coming from a Layouts cell, do not apply stored post type options... maybe
			return;
		}
		*/
		$stored_settings = WPV_Settings::get_instance();
		$wpv_post_types_for_archive_loop = $stored_settings->wpv_post_types_for_archive_loop;
		$stored_settings_per_type = isset( $wpv_post_types_for_archive_loop[ $this->wpa_type ] ) ? $wpv_post_types_for_archive_loop[ $this->wpa_type ] : array();
		$stored_settings_per_loop = isset( $stored_settings_per_type[ $this->wpa_name ] ) ? $stored_settings_per_type[ $this->wpa_name ] : array();

		if (
			empty( $stored_settings_per_loop )
			&& 'taxonomy' === $this->wpa_type
			&& in_array( $this->wpa_name, array( 'category', 'post_tag' ) )
		) {
			$stored_settings_per_loop = $this->get_default_post_types_for_native_taxonomy( $this->wpa_name );
		}

		if ( ! empty( $stored_settings_per_loop ) ) {
			$query->set('post_type', $stored_settings_per_loop );
		}
	}

	/**
	 * Adjust the post types assigned to a WPA used on native taxonomies.
	 *
	 * No post type setting means query only for posts, which breaks the archive loop query.
	 * We need to manually enforce CPTs assigned to native taxonomies.
	 *
	 * @param string $taxonomy
	 *
	 * @return array
	 *
	 * @since 2.6.2
	 */
	function get_default_post_types_for_native_taxonomy( $taxonomy ) {
		$types_cpt = get_option('wpcf-custom-types');
		if (
			! is_array( $types_cpt )
			|| empty( $types_cpt )
		) {
			$types_cpt = array();
		}
		$post_types_for_native = array( 'post' );

		foreach ( $types_cpt as $cpt_slug => $cpt ) {
			if (
				array_key_exists( 'taxonomies', $cpt )
				&& is_array( $cpt['taxonomies'] )
			) {
				foreach ( $cpt['taxonomies'] as $tax_slug => $value ) {
					if (
						$taxonomy == $tax_slug
						&& $value
					) {
						$post_types_for_native[] = $cpt_slug;
					}
				}
			}
		}

		return $post_types_for_native;
	}

	/**
	* archive_apply_order_settings
	*
	* Apply sorting settings for WordPress Archives.
	* By now, just two settings: orderby and order.
	*
	* $archive_settings = array(
	*	'orderby'	=> 'post_date'|...,
	*	'order'		=> 'ASC'|'DESC'
	* 	'orderby_as'	=> ''|'STRING'|'NUMERIC'
	* );
	*
	* @since 2.1
	*
	* @todo The posted sorting options demand the wpv_view_count URL parameter, which we are not posting now
	*/

	function archive_apply_order_settings( $query, $archive_settings, $archive_id ) {

		if ( $query->get( 'wpv_dependency_query' ) ) {
			return;
		}

		$is_view_posted = false;
		if ( isset( $_GET['wpv_view_count'] ) ) {
			$view_unique_hash = apply_filters( 'wpv_filter_wpv_get_object_unique_hash', '', $archive_settings );
			if ( esc_attr( $_GET['wpv_view_count'] ) == $view_unique_hash ) {
				$is_view_posted = true;
				// Map old URL parameters to new ones
				do_action( 'wpv_action_wpv_pagination_map_legacy_order' );
			}
		}

		$order		= $archive_settings['order'];
		$orderby	= $archive_settings['orderby'];
		$orderby_as	= $archive_settings['orderby_as'];

		$order_second	= $archive_settings['order_second'];
		$orderby_second	= $archive_settings['orderby_second'];

		$valid_orderby_second	= array(
			'date', 'post_date', 'post-date',
			'title', 'post_title', 'post-title',
			'id', 'post_id', 'post-id', 'ID',
			'author', 'post_author', 'post-author',
			'type', 'post_type', 'post-type',
			'modified', 'menu_order', 'rand'
		);

		// Modern order URL override
		if ( $is_view_posted ) {
			if (
				isset( $_GET['wpv_sort_order'] )
				&& in_array( strtoupper( esc_attr( $_GET['wpv_sort_order'] ) ), array( 'ASC', 'DESC' ) )
			) {
				$order = strtoupper( esc_attr( $_GET['wpv_sort_order'] ) );
			}

			if (
				isset( $_GET['wpv_sort_orderby'] )
				&& esc_attr( $_GET['wpv_sort_orderby'] ) != 'undefined'
				&& esc_attr( $_GET['wpv_sort_orderby'] ) != ''
			) {
				$orderby = esc_attr( $_GET['wpv_sort_orderby'] );
			}

			if (
				isset( $_GET['wpv_sort_orderby_as'] )
				&& in_array( strtoupper( esc_attr( $_GET['wpv_sort_orderby_as'] ) ), array( 'STRING', 'NUMERIC' ) )
			) {
				$orderby_as = strtoupper( esc_attr( $_GET['wpv_sort_orderby_as'] ) );
			}

			// Secondary sorting
			if (
				isset( $_GET['wpv_sort_order_second'] )
				&& in_array( strtoupper( esc_attr( $_GET['wpv_sort_order_second'] ) ), array( 'ASC', 'DESC' ) )
			) {
				$order_second = strtoupper( esc_attr( $_GET['wpv_sort_order_second'] ) );
			}

			if (
				isset( $_GET['wpv_sort_orderby_second'] )
				&& esc_attr( $_GET['wpv_sort_orderby_second'] ) != 'undefined'
				&& esc_attr( $_GET['wpv_sort_orderby_second'] ) != ''
				&& in_array( $_GET['wpv_sort_orderby_second'], $valid_orderby_second )
			) {
				$orderby_second = esc_attr( $_GET['wpv_sort_orderby_second'] );
			}
		}

		if ( strpos( $orderby, 'field-' ) === 0 ) {
			$meta_key = substr( $orderby, 6 );
			$type = $orderby_as;
			$is_types_field_data = wpv_is_types_custom_field ( $meta_key );
			if (
				$is_types_field_data
				&& isset( $is_types_field_data['meta_key'] )
				&& isset( $is_types_field_data['type'] )
			) {
				$meta_key = $is_types_field_data['meta_key'];
				$type = $is_types_field_data['type'];
			}

			// User preference overrides the auto-discover
			if (
					isset( $orderby_as )
					&& in_array( $orderby_as, array( 'STRING', 'NUMERIC' ) )
			) {
				switch ( $orderby_as ) {
					case "STRING":
						$orderby = 'meta_value';
						break;
					case "NUMERIC":
						$orderby = 'meta_value_num';
						break;
				}
			} elseif ( in_array( $type, array( 'numeric', 'date' ) ) ) {	// Auto-Discover
				$orderby = 'meta_value_num';
			} else {
				$orderby = 'meta_value';
			}

			$query->set( 'meta_key', $meta_key );

		}

		// Normalize orderby and orderby_second options
		$orderby		= WPV_Sorting_Embedded::normalize_post_orderby_value( $orderby );
		$orderby_second	= WPV_Sorting_Embedded::normalize_post_orderby_value( $orderby_second );

		global $wp_version;
		if (
			! version_compare( $wp_version, '4.0', '<' )
			&& $orderby != 'rand'
			&& $orderby_second != ''
			&& $orderby != $orderby_second
		) {
			$orderby_array = array(
				$orderby		=> $order,
				$orderby_second	=> $order_second
			);
			$query->set( 'orderby',	$orderby_array );
		} else {
			$query->set( 'orderby', $orderby );
			$query->set( 'order', $order );
			$query->set( 'wpv_orderby', $orderby );
			$query->set( 'wpv_order', $order );
		}

	}

	/**
	* archive_apply_pagination_settings
	*
	* Apply pagination settings for WordPress Archives.
	* By now, just two settings: pagintion>mode and pagination>posts_per_page.
	*
	* $archive_settings['pagination'] = array(
	*	'mode'				=> 'disabled'|'paged'(|'ajaxed'|'rollover'?),
	*	'posts_per_page'	=> 'default'|(int)
	* );
	*
	* @since 2.1
	*/

	function archive_apply_pagination_settings( $query, $archive_settings, $archive_id ) {

		if ( $query->get( 'wpv_dependency_query' ) ) {
			return;
		}

		// Validate stored settings
		$archive_settings['pagination']['type']				=
			( isset( $archive_settings['pagination']['type'] ) && in_array( $archive_settings['pagination']['type'], array( 'disabled', 'paged', 'ajaxed', 'rollover' ) ) ) ?
				$archive_settings['pagination']['type'] :
				'paged';
		$archive_settings['pagination']['posts_per_page']	=
			( isset( $archive_settings['pagination']['posts_per_page'] ) ) ?
				$archive_settings['pagination']['posts_per_page'] :
				'default';

		// Apply settings
		if ( $archive_settings['pagination']['type'] == 'disabled' ) {
			$query->set( 'posts_per_page', -1 );
		} else if ( $archive_settings['pagination']['posts_per_page'] != 'default' ) {
			$query->set( 'posts_per_page', (int) $archive_settings['pagination']['posts_per_page'] );
		}

	}

	static function extend_archive_query_for_parametric_and_counters( $post_query, $archive_settings, $archive_id ) {
		$dps_enabled		= false;
		$counters_enabled	= false;

		if (
			! isset( $archive_settings['dps'] )
			|| ! is_array( $archive_settings['dps'] )
		) {
			$archive_settings['dps'] = array();
		}
		if (
			isset( $archive_settings['dps']['enable_dependency'] )
			&& $archive_settings['dps']['enable_dependency'] == 'enable'
		) {
			$dps_enabled = true;
			$controls_per_kind = wpv_count_filter_controls( $archive_settings );
			$controls_count = 0;
			$no_intersection = array();
			if ( ! isset( $controls_per_kind['error'] ) ) {
				$controls_count = $controls_per_kind['cf'] + $controls_per_kind['tax'] + $controls_per_kind['pr'] + $controls_per_kind['search'];
				if (
					$controls_per_kind['cf'] > 1
					&& (
						! isset( $archive_settings['custom_fields_relationship'] )
						|| $archive_settings['custom_fields_relationship'] != 'AND'
					)
				) {
					$no_intersection[] = __( 'custom field', 'wpv-views' );
				}
				if (
					$controls_per_kind['tax'] > 1
					&& (
						! isset( $archive_settings['taxonomy_relationship'] )
						|| $archive_settings['taxonomy_relationship'] != 'AND'
					)
				) {
					$no_intersection[] = __( 'taxonomy', 'wpv-views' );
				}
			} else {
				$dps_enabled = false;
			}
			if ( $controls_count > 0 ) {
				if ( count( $no_intersection ) > 0 ) {
					$dps_enabled = false;
				}
			} else {
				$dps_enabled = false;
			}
		}
		if ( ! isset( $archive_settings['filter_meta_html'] ) ) {
			$archive_settings['filter_meta_html'] = '';
		}
		if ( strpos( $archive_settings['filter_meta_html'], '%%COUNT%%' ) !== false ) {
			$counters_enabled = true;
		}

		if (
			! $dps_enabled
			&& ! $counters_enabled
		) {
			// Set the force value
			do_action( 'wpv_action_wpv_force_disable_dps', true );
			return;
		} else {
			do_action( 'wpv_action_wpv_force_disable_dps', false );
		}

		$already = array();
		if (
			isset( $post_query->posts )
			&& ! empty( $post_query->posts )
		) {
			foreach ( (array) $post_query->posts as $post_object ) {
				$already[] = $post_object->ID;
			}
		}

		$query_args = $post_query->query_vars;

		$override_settings = array();
		if ( isset( $query_args['post_type'] ) ) {
			$override_settings['post_type'] = is_array( $query_args['post_type'] ) ? $query_args['post_type'] : array( $query_args['post_type'] );
		}

		$parametric_search_data_to_cache = WPV_Cache::get_parametric_search_data_to_cache( $archive_settings, $override_settings );

		WPV_Cache::generate_native_cache( $already, $parametric_search_data_to_cache );

		if ( isset ( $query_args['pr_filter_post__in'] ) ) {
			$query_args['post__in'] = $query_args['pr_filter_post__in'];
		} else {
			// If just for the missing ones, generate the post__not_in argument
			if ( isset( $query_args['post__not_in'] ) ) {
				$query_args['post__not_in'] = array_merge( (array) $query_args['post__not_in'], (array) $already );
			} else {
				$query_args['post__not_in'] = (array) $already;
			}
			// And adjust on the post__in argument
			if ( isset( $query_args['post__in'] ) ) {
				$query_args['post__in'] = array_diff( (array) $query_args['post__in'], (array) $query_args['post__not_in'] );
			}
		}

		$keys = array(
			'error',
			//'m',
			//'p',
			//'post_parent',
			'subpost',
			'subpost_id',
			'attachment',
			'attachment_id',
			'name',
			'static',
			'pagename',
			'page_id',
			//'second',
			//'minute',
			//'hour',
			//'day',
			//'monthnum',
			//'year',
			//'w',
			//'category_name',
			//'tag',
			//'cat',
			//'tag_id',
			//'author',
			//'author_name',
			'feed',
			'tb',
			'paged',
			//'meta_key',
			//'meta_value',
			'preview',
			//'s',
			'sentence',
			'title',
			//'fields',
			'menu_order',
			'embed',
			'wpv_fake_archive_loop'
		);

		foreach ( $keys as $k ) {
			if ( isset( $query_args[$k] ) ) {
				unset( $query_args[$k] );
			}
		}

		$query_args['nopaging'] 		= true;
		$query_args['fields'] 			= 'ids';
		$query_args['posts_per_page']	= -1;

		/**
		 * Before performing the auxiliar query for calculating avalable form inputs, or calculate counters.
		 *
		 * @param array $query_args
		 * @since 2.9
		 */
		do_action( 'wpv_action_wpv_before_extended_archive_query_for_parametric_and_counters', $query_args );

		$aux_cache_query = new WP_Query( $query_args );

		/**
		 * After performing the auxiliar query for calculating avalable form inputs, or calculate counters.
		 *
		 * @param array $query_args
		 * @param WP_Query $aux_cache_query
		 * @since 2.9
		 */
		do_action( 'wpv_action_wpv_after_extended_archive_query_for_parametric_and_counters', $query_args, $aux_cache_query );

		// Add the auxiliar query results to the list of returned IDs
		// Generate the "extra" cache
		if (
			is_array( $aux_cache_query->posts )
			&& ! empty( $aux_cache_query->posts )
		) {
			WPV_Cache::generate_cache( $aux_cache_query->posts, $parametric_search_data_to_cache );
		}
	}

	function wpv_get_dependant_archive_query_args( $args = array(), $archive_settings = array(), $affected_data = array() ) {
		if (
			isset( $archive_settings['view-query-mode'] )
			&& $archive_settings['view-query-mode'] != 'normal'
		) {
			$wpa_loop = array(
				'type'	=> $this->wpa_type,
				'name'	=> $this->wpa_name,
				'data'	=> $this->wpa_data,
				'id'	=> $this->wpa_id
			);
			$args = $this->fake_archive_query( $wpa_loop );
			$args['posts_per_page'] 		= -1;
			$args['limit'] 					= -1;
			$args['paged'] 					= 1;
			$args['offset'] 				= 0;
			$args['fields'] 				= 'ids';
			$args['wpv_dependency_query']	= $affected_data;
		}
		return $args;
	}

	/**
	* initialize_archive_loop
	*
	* @todo check whether we can rename this safely
	* @todo check whether we can move this to the wp hook - TOO EARLY
	*
	* @since unknown
	*/

	function initialize_archive_loop() {

		$wpa_id		= $this->wpa_id;
		$wpa_slug	= $this->wpa_slug;

		if ( ! $wpa_id ) {
			return;
		}

		global $wp_query;

		do_action( 'wpv_action_before_initialize_archive_loop', $wpa_id, $wpa_slug );

		if ( ! have_posts() ) {
			// We need to handle empty loops and force the loop processing
			// Create a dummy WP_Post and set the post count to 1
			// That will fire the loop_start and loop_end hooks
			$wp_query->post_count = 1;
			$dummy_post_obj = (object) array(
				'ID'				=> $wpa_id,
				'post_author'		=> '1',
				'post_name'			=> '',
				'post_type'			=> '',
				'post_title'		=> '',
				'post_date'			=> '0000-00-00 00:00:00',
				'post_date_gmt'		=> '0000-00-00 00:00:00',
				'post_content'		=> '',
				'post_excerpt'		=> '',
				'post_status'		=> 'publish',
				'comment_status'	=> 'closed',
				'ping_status'		=> 'closed',
				'post_password'		=> '',
				'post_parent'		=> 0,
				'post_modified'		=> '0000-00-00 00:00:00',
				'post_modified_gmt'	=> '0000-00-00 00:00:00',
				'comment_count'		=> '0',
				'menu_order'		=> '0'
			);
			$dummy_post = new WP_Post( $dummy_post_obj );
			$wp_query->posts = array( $dummy_post );
			$this->loop_has_no_posts = true;
		}
		if ( have_posts() ) {
			$output_post = get_post( $wpa_id );
            if ( $output_post ) {
				// Save the original query.
				$action_args = array(
					'wpa_id'		=> $wpa_id,
					'wpa_slug'		=> $wpa_slug,
					'wpa_settings'	=> $this->wpa_settings,
					'wpa_object'	=> $this
				);
				do_action( 'wpv_action_wpv_before_clone_archive_loop', $wp_query, $action_args );
				$this->query = ( $wp_query instanceof WP_Query ) ? clone $wp_query : null;
				add_action( 'loop_start',	array( $this, 'loop_start' ), 1, 1 );
				add_action( 'loop_end',		array( $this, 'loop_end' ), 999, 1 );
				add_action( 'get_header',	array( $this, 'get_header' ) );
				// Prevent the view from being displayed in the head.
				// JetPack can cause this.
				add_action( 'wp_head',		array( $this, 'html_head_start' ), -100 ); // try to load first
				add_action( 'wp_head',		array( $this, 'html_head_end' ), 999 ); // try to load last
			}
		}

		do_action( 'wpv_action_extend_archive_query_for_parametric_and_counters', $wp_query, $this->wpa_settings, $wpa_id );

	}

	function force_disable_404() {
		if ( ! is_null( $this->wpa_id ) ) {
			global $wp_query;
			if ( $wp_query->is_404 ) {
				$wp_query->is_404 = false;
			}
		}
	}


	function get_archive_loop_query() {
		if ( $this->in_the_loop ) {
			return $this->query;
		}
	}


	function get_header( $name ) {
		$this->header_started = true;
	}


	function html_head_start() {
		$this->in_head = true;
	}


	function html_head_end() {
		$this->in_head = false;
	}


	/**
	 * Generates a WPA Archive Edit link based on it's post id.
	 *
	 * @param int $post_id Post id for WPA Archive.
	 * @return mixed|void
	 */
	public static function archive_edit_link( $post_id ) {
		return apply_filters(
			'wpv_filter_wpa_edit_link',
			add_query_arg(
				array(
					'page' => 'view-archives-editor',
					'view_id' => $post_id,
				),
				admin_url( 'admin.php' )
			),
			$post_id
		);
	}

	/**
	 * Returns an array with the terms slugs that are assigned to the current archive.
	 *
	 * @param WP_Post $archive_post Post referencing the WPA.
	 * @param string $taxonomy_slug The taxonomy slug.
	 *
	 * @return string[]
	 */
	public function get_archive_taxonomy_terms( $archive_post, $taxonomy_slug ) {
		$pattern_template = self::SETTINGS_TAXONOMY_LOOP_OPTION_REGEXP_TEMPLATE;
		$settings_term_options_pattern = sprintf( $pattern_template, $taxonomy_slug );
		$settings_terms = $this->wpv_settings->preg_key( $settings_term_options_pattern );
		$selected_terms = [];

		foreach ( $settings_terms as $settings_term_key ) {
			if ( intval( $archive_post->ID ) === $this->wpv_settings[ $settings_term_key ] ) {
				$term_matches = [];
				preg_match( $settings_term_options_pattern, $settings_term_key, $term_matches );
				if ( count( $term_matches ) > 0 ) {
					$selected_terms[] = $term_matches[1];
				}
			}
		}

		return $selected_terms;
	}

	function loop_start( $query ) {
		if (
			! $this->in_head
			&& $this->header_started
			&& $query->is_main_query()
			&& (
				$query->query_vars_hash == $this->query->query_vars_hash
				|| $query->request == $this->query->request
			)
		) {
			ob_start();
			$this->post_count = $query->post_count;
			$query->post_count = 1;
			$this->loop_found = true;
		}
	}


	function loop_end( $query ) {
		if (
			$this->loop_found
			&& $query->is_main_query()
		) {
			ob_end_clean();

			if ( $this->loop_has_no_posts ) {
				// Reset everything if the loop has no posts.
				// Then the View will render with no posts.

				global $post, $wp_query;

				$this->post_count = 0;
				$this->query->post_count = 0;
				$wp_query->post_count = 0;

				$wp_query->posts = array();
				$this->query->posts = array();

				$post = null;
			}

			$query->post_count = $this->post_count;

			$this->in_the_loop = true;

			$wpa_output = render_view( array( 'id' => $this->wpa_id ) );

			// For the case where the "toolset_the_content_wpa" filter is applied to the output of a WordPress Archive, the "wpautop" callback
			// is moved to the next priority in which the filter is applied to the WordPress Archive output to prevent undesired
			// markup.
			$priority = has_filter( 'toolset_the_content_wpa', 'wpautop' ) ?: 10;
			remove_filter( 'toolset_the_content_wpa', 'wpautop', $priority );

			/**
			 * Filtering the content of the WordPress Archive output.
			 *
			 * @param string $wpa_output The output of the current WordPress Archive.
			 *
			 * @return string
			 */
			$wpa_output = apply_filters( 'toolset_the_content_wpa', $wpa_output );

			// Here we are restoring the removed "wpautop" callback hooked in the "the_content" filter.
			add_filter( 'toolset_the_content_wpa', 'wpautop', $priority );

			// Because escaping is supposed to be handled already in `render_view()` and `the_content` filters:
			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo $wpa_output;

			$this->in_the_loop = false;

			$this->loop_found = false;
		}

	}

	/**
	 * @deprecated Use $this->get_archive_loops() instead.
	 * @return array
	 */
	function _get_post_type_loops() {
		$loops = array(
			'home-blog-page'	=> __('Home/Blog', 'wpv-views'),
			'search-page'		=> __('Search results', 'wpv-views'),
			'author-page'		=> __('Author archives', 'wpv-views'),
			'year-page'			=> __('Year archives', 'wpv-views'),
			'month-page'		=> __('Month archives', 'wpv-views'),
			'day-page'			=> __('Day archives', 'wpv-views')
		);

		// Only offer loops for post types that already have an archive
		$post_types = get_post_types( array( 'public'=>true, 'has_archive' => true ), 'objects' );
		foreach ( $post_types as $post_type ) {
			if ( ! in_array( $post_type->name, array( 'post', 'page', 'attachment' ) ) ) {
				$type = 'cpt_' . $post_type->name;
				$name = $post_type->labels->name;
				$loops[ $type ] = $name;
			}
		}

		return $loops;
	}


	/**
	 * Wrapper of get_archive_loops only for post_types, returns the array indexed with the post type name as key.
	 *
	 * @param bool $include_wpa Optional. Determines whether the information about WPA assigned to this loop should be
	 *     retrieved (the $wpa element). Default is false.
	 * @param bool $include_ct Optional. Determines whether the information about CT assigned to given post type archive
	 *     or taxonomy archive should be retrieved (the $ct element). Default is false.
	 * @param bool $noexclude Optional. If true, no loops of given type will be excluded. Default is false.
	 *
	 * @return array An array of information about native archive loops and loops for custom post types and taxonomies.
	 *     Each element is an array representing one loop:
	 *     array(
	 *         @type string $slug Unique slug (within loop type) as used in other parts of Views.
	 *         @type string $display_name Display name for the loop.
	 *         @type string $post_type_name For 'post_type' loop type, this will contain "raw" post type slug.
	 *         @type string $loop_type 'native'|'post_type'|'taxonomy'
	 *         @type int $wpa If $include_wpa is true, this contains an ID of WPA assigned to this loop, or zero if
	 *             no WPA is assigned.
	 *         @type int $ct If $include_ct is true, this contains an ID of CT assigned to this custom post type
	 *             archive or taxonomy archive, or zero if no CT is assigned. This element isn't present for native loops.
	 *         @type int $single_ct If $include_ct is true, this contains an ID of CT assigned to single posts of
	 *             this custom post type, or zero if no CT is assigned. This element is present only for post types.
	 *     )
	 */
	public function get_indexed_post_type_loops( $include_wpa = false, $include_ct = false, $noexclude = false ) {
		$loops = $this->get_archive_loops( 'post_type', $include_wpa, $include_ct, $noexclude );
		$indexed_loops = [];
		foreach ( $loops as $loop ) {
			$indexed_loops[ $loop['post_type_name'] ] = $loop;
		}
		return $indexed_loops;
	}


	/**
	 * Get information about currently existing archive loops.
	 *
	 * @param string $loop_type Optional. Desired type of loops. 'native'|'post_type'|'taxonomy'|'all'. Default is 'all'.
	 * @param bool $include_wpa Optional. Determines whether the information about WPA assigned to this loop should be
	 *     retrieved (the $wpa element). Default is false.
     * @param bool $include_ct Optional. Determines whether the information about CT assigned to given post type archive
     *     or taxonomy archive should be retrieved (the $ct element). Default is false.
     * @param bool $noexclude Optional. If true, no loops of given type will be excluded. Default is false.
	 *
	 * @return array An array of information about native archive loops and loops for custom post types and taxonomies.
	 *     Each element is an array representing one loop:
	 *     array(
	 *         @type string $slug Unique slug (within loop type) as used in other parts of Views.
	 *         @type string $display_name Display name for the loop.
	 *         @type string $post_type_name For 'post_type' loop type, this will contain "raw" post type slug.
	 *         @type string $loop_type 'native'|'post_type'|'taxonomy'
	 *         @type int $wpa If $include_wpa is true, this contains an ID of WPA assigned to this loop, or zero if
	 *             no WPA is assigned.
     *         @type int $ct If $include_ct is true, this contains an ID of CT assigned to this custom post type
     *             archive or taxonomy archive, or zero if no CT is assigned. This element isn't present for native loops.
     *         @type int $single_ct If $include_ct is true, this contains an ID of CT assigned to single posts of
     *             this custom post type, or zero if no CT is assigned. This element is present only for post types.
	 *     )
	 *
	 * @since 1.7
	 *
     * @todo consider implementing caching mechanism
	 */
	public function get_archive_loops( $loop_type = 'all', $include_wpa = false, $include_ct = false, $noexclude = false ) {

		$stored_settings = $this->wpv_settings;

		switch( $loop_type ) {

			case 'native':
				$loops = array(
					array(
						'slug'			=> 'home-blog-page',
						'option'		=> 'view_home-blog-page',
						'loop_type'		=> 'native',
						'display_name'	=> __( 'Home/Blog', 'wpv-views' )
					),
					array(
						'slug'			=> 'search-page',
						'option'		=> 'view_search-page',
						'loop_type'		=> 'native',
						'display_name'	=> __( 'Search results', 'wpv-views' )
					),
					array(
						'slug'			=> 'author-page',
						'option'		=> 'view_author-page',
						'loop_type'		=> 'native',
						'display_name'	=> __( 'Author archives', 'wpv-views' )
					),
					array(
						'slug'			=> 'year-page',
						'option'		=> 'view_year-page',
						'loop_type'		=> 'native',
						'display_name'	=> __( 'Year archives', 'wpv-views' )
					),
					array(
						'slug'			=> 'month-page',
						'option'		=> 'view_month-page',
						'loop_type'		=> 'native',
						'display_name'	=> __( 'Month archives', 'wpv-views' )
					),
					array(
						'slug'			=> 'day-page',
						'option'		=> 'view_day-page',
						'loop_type'		=> 'native',
						'display_name'	=> __( 'Day archives', 'wpv-views' )
					)
				);

				if ( $include_wpa ) {
					$loop_count = count( $loops );
					for( $i = 0; $i < $loop_count; ++$i ) {
						$option = $loops[ $i ]['option'];
						$loops[ $i ]['wpa'] = isset( $stored_settings[ $option ] ) ? $stored_settings[ $option ] : 0;
					}
				}
				return $loops;

			case 'post_type':

				$pt_loops = array();
				// Only offer loops for post types that already have an archive, unless $noexclude is given
                $pt_query_args = array( 'public' => true );
                if ( ! $noexclude ) {
                    $pt_query_args['has_archive'] = true;
                }
				$post_types = get_post_types( $pt_query_args, 'objects' );

				foreach ( $post_types as $post_type ) {
					if (
						$noexclude
						|| ! in_array( $post_type->name, array( 'post', 'page', 'attachment' ) )
					) {

						$loop = array(
							'slug'				=> 'cpt_' . $post_type->name,
							'post_type_name'	=> $post_type->name,
							'option'			=> 'view_cpt_' . $post_type->name,
							'display_name'		=> $post_type->labels->name,
							'singular_name'		=> $post_type->labels->singular_name,
							'loop_type'			=> 'post_type'
						);

						if( $include_wpa ) {
							$loop['wpa'] = isset( $stored_settings[ $loop['option'] ] ) ? $stored_settings[ $loop['option'] ] : 0;
						}

                        if( $include_ct ) {

                        	$content_template_archive_settings_key = sprintf(
                        		'%s%s',
								\WPV_Settings::CPT_ARCHIVES_CT_ASSIGNMENT_PREFIX,
								$post_type->name
							);

							$content_template_conditions_settings_key = sprintf(
								'%s%s',
								\WPV_Settings::SINGLE_POST_TYPES_CT_CONDITIONS_ASSIGNMENT_PREFIX,
								$post_type->name
							);

							$content_template_settings_key = sprintf(
								'%s%s',
								\WPV_Settings::SINGLE_POST_TYPES_CT_ASSIGNMENT_PREFIX,
								$post_type->name
							);

							$loop[ self::KEY_LOOP_ARCHIVE_CT ] = wpv_getarr( $stored_settings, $content_template_archive_settings_key, 0 );
							$loop[ self::KEY_LOOP_SINGLE_CT ] = wpv_getarr( $stored_settings, $content_template_settings_key, 0 );

							$loop[ self::KEY_LOOP_SINGLE_CT_CONDITIONS ] = UsagePostType::createFromDatabaseArray(
								$loop[ self::KEY_LOOP_SINGLE_CT ],
								wpv_getarr( $stored_settings, $content_template_conditions_settings_key, [] )
							);

                        }

						$pt_loops[ $post_type->name ] = $loop;
					}
				}

				return $pt_loops;

			case 'taxonomy':

				$tx_loops = array();
				$taxonomies = get_taxonomies( '', 'objects' );
				$exclude_tax_slugs = array();
                if ( ! $noexclude ) {
                    $exclude_tax_slugs = apply_filters( 'wpv_admin_exclude_tax_slugs', $exclude_tax_slugs );
                }
				foreach ( $taxonomies as $taxonomy_slug => $taxonomy ) {
					if ( in_array( $taxonomy_slug, $exclude_tax_slugs ) ) {
						continue;
					}
					// Only show taxonomies with show_ui set to TRUE
					if ( ! $taxonomy->show_ui ) {
						continue;
					}

					$loop = array(
						'slug'			=> $taxonomy->name,
						'option'		=> 'view_taxonomy_loop_' . $taxonomy->name,
						'display_name'	=> $taxonomy->labels->name,
						'loop_type'		=> 'taxonomy'
					);

					if ( $include_wpa ) {
						$loop['wpa'] = isset( $stored_settings[ $loop['option'] ] ) ? $stored_settings[ $loop['option'] ] : 0;
						$loop['wpa_options'] = $this->get_archive_settings_for_taxonomy_terms( $taxonomy->name );
					}

                    if ( $include_ct ) {
                        $loop['ct'] = wpv_getarr( $stored_settings, "views_template_loop_{$taxonomy->name}", 0 );
                    }

					$tx_loops[] = $loop;
				}

				return $tx_loops;

			case 'all':
			default:
				return array_merge(
					$this->get_archive_loops( 'native', $include_wpa ),
					$this->get_archive_loops( 'post_type', $include_wpa ),
					$this->get_archive_loops( 'taxonomy', $include_wpa )
				);
		}
	}

	function _view_edit_options( $view_id, $options ) { // MAYBE DEPRECATED
		static $js_added = false;

		$title = '';
		if (isset($_GET['view_archive'])) {
			$options['view_' . $_GET['view_archive']] = $view_id;
			$loops = $this->_get_post_type_loops();
			$title = sprintf('%s-archive', $loops[$_GET['view_archive']]);
		}

		if (isset($_GET['view_archive_taxonomy'])) {
			$options['view_taxonomy_loop_' . $_GET['view_archive_taxonomy']] = $view_id;
			$taxonomies = get_taxonomies('', 'objects');
			$title = sprintf('%s-taxonomy-archive', $taxonomies[$_GET['view_archive_taxonomy']]->labels->name);
		}

		if ($title != '' && !$js_added) {
			// add some js to set the post title.

			?>
			<script type="text/javascript">
				jQuery(function($){
					jQuery('#title').val('<?php echo esc_js($title); ?>');
				});
			</script>
			<?php
			$js_added = true;
		}

		return $options;
	}

	/**
	 * Prints the archive creation popup
	 */
	public function create_view_archive_popup() {
		printf(
			self::CREATE_ARCHIVE_POPUP_TEMPLATE,
			esc_attr( __( 'Name this WordPress Archive', 'wpv-views' ) ),
			esc_attr( __( 'WordPress Archive name', 'wpv-views' ) )
		);
	}


	public function check_archive_loops_exists() {
		$stored_settings = $this->wpv_settings;

		$loops = $this->_get_post_type_loops();

		$settings_array = $stored_settings->get();// @todo this might not be needed as it implements ArrayAccess anyway

		foreach ( $loops as $loop => $loop_name ) {

			if (
				isset( $settings_array[ 'view_' . $loop ] )
				&& $settings_array[ 'view_' . $loop ] !== 0
			) {
				unset( $loops[ $loop ] );
			}

		}

		$taxonomies = get_taxonomies( '', 'objects' );
		$exclude_tax_slugs = array();
		$exclude_tax_slugs = apply_filters( 'wpv_admin_exclude_tax_slugs', $exclude_tax_slugs );

		foreach ( $taxonomies as $category_slug => $category ) {

			if ( in_array( $category_slug, $exclude_tax_slugs ) ) {
				unset( $taxonomies[ $category_slug ] );
				continue;
			}
			if ( ! $category->show_ui ) {
				unset( $taxonomies[ $category_slug ] );
				continue; // Only show taxonomies with show_ui set to TRUE
			}

			if (
				isset( $settings_array[ 'view_taxonomy_loop_' . $category_slug ] )
				&& $settings_array[ 'view_taxonomy_loop_' . $category_slug ] !== 0
			) {
				unset( $taxonomies[ $category_slug ] );
			}

		}


		return ! ( empty( $loops ) && empty( $taxonomies ) );
	}


	function update_view_archive_settings( $post_id, $data ) {
		$stored_settings = $this->wpv_settings;

		$found = false;

		// clear existing ones
		$loops = $this->_get_post_type_loops();
		foreach ( $loops as $type => $name ) {
			if (
				isset( $stored_settings['view_' . $type] )
				&& $stored_settings['view_' . $type] == $post_id
			) {
				unset( $stored_settings['view_' . $type] );
				$found = true;
			}
		}
		$taxonomies = get_taxonomies( '', 'objects' );
		foreach ( $taxonomies as $category_slug => $category ) {
			if (
				isset( $stored_settings['view_taxonomy_loop_' . $category_slug] )
				&& $stored_settings['view_taxonomy_loop_' . $category_slug] === $post_id
			) {
				unset( $stored_settings['view_taxonomy_loop_' . $category_slug] );
				$found = true;
			}

			$pattern_template = self::SETTINGS_TAXONOMY_LOOP_OPTION_REGEXP_TEMPLATE;
			$settings_term_options_pattern = sprintf( $pattern_template, $category_slug );
			$settings_terms = $stored_settings->preg_key( $settings_term_options_pattern );

			foreach ( $settings_terms as $settings_term_key ) {
				if ( $stored_settings[ $settings_term_key ] === $post_id ) {
					unset( $stored_settings[ $settings_term_key ] );
					$found = true;
				}
			}
		}

		foreach ( $data as $key => $value ) {
			$key = sanitize_text_field( $key );
			if ( strpos( $key, 'wpv-view-loop-' ) === 0 ) {
				preg_match( '/wpv-view-loop-(.*)/', $key, $out );
				$stored_settings['view_' . $out[1]] = $post_id;
				$found = true;
			}
			if ( strpos( $key, 'wpv-view-taxonomy-loop-' ) === 0 ) {
				$stored_settings['view_taxonomy_loop_' . substr( $key, 23 )] = $post_id;
				$found = true;
			}
			if ( strpos( $key, 'view_taxonomy_option_loop_' ) === 0 ) {
				$stored_settings[ $key ] = (int) $post_id;
				$found = true;
			}
		}

        $stored_settings->refresh_view_settings_data();

		if ( $found ) {
            $stored_settings->save();
		}
	}

	function wpv_wpa_fix_woocommerce_archives( $wpa_to_apply, $wpa_slug ) {
		global $post, $wp_query;
		if ( ! have_posts() ) {
			add_filter( 'woocommerce_redirect_single_search_result', '__return_false' );
		}
	}

	function wpv_get_current_archive( $current_archive = null ) {
		return $this->wpa_id;
	}

	function wpv_get_current_archive_loop( $current_archive_loop = array() ) {
		return array(
			'type'	=> $this->wpa_type,
			'name'	=> $this->wpa_name,
			'data'	=> $this->wpa_data
		);
	}

	function wpv_get_archive_unique_hash( $unique_hash = '' ) {
		$unique_hash = $this->get_archive_unique_hash();
		return $unique_hash;
	}

	function get_archive_unique_hash() {
		if ( ! $this->wpa_id ) {
			return '';
		}
		return (string) $this->wpa_id;
	}

	function extend_pagination_settings( $pagination_data, $view_settings ) {
		switch ( $pagination_data['query'] ) {
			case 'archive':
				$pagination_data['loop'] = array(
					'type'	=> $this->wpa_type,
					'name'	=> $this->wpa_name,
					'data'	=> $this->wpa_data,
					'id'	=> $this->wpa_id
				);
				break;
			default:
				$pagination_data['loop'] = array(
					'type'	=> '',
					'name'	=> '',
					'data'	=> array(),
					'id'	=> 0
				);
				break;
		}
		return $pagination_data;
	}

	function extend_parametric_settings( $parametric_data, $view_settings ) {
		switch ( $parametric_data['query'] ) {
			case 'archive':
				$parametric_data['loop'] = array(
					'type'	=> $this->wpa_type,
					'name'	=> $this->wpa_name,
					'data'	=> $this->wpa_data,
					'id'	=> $this->wpa_id
				);
				break;
			default:
				$parametric_data['loop'] = array(
					'type'	=> '',
					'name'	=> '',
					'data'	=> array(),
					'id'	=> 0
				);
				break;
		}
		return $parametric_data;
	}

	function fake_archive_query( $loop ) {
		$this->wpa_id		= $loop['id'];
		$this->wpa_settings	= apply_filters( 'wpv_filter_wpv_get_view_settings', array(), $loop['id'] );
		$query_args			= array(
			'wpv_fake_archive_loop'	=> $loop,
			// Disable ElasticPress for this query.
			'ep_integrate' => false,
		);
		switch ( $loop['type'] ) {
			// 'native'|'post_type'|'taxonomy'
			case 'native':
				$query_args = $this->fake_archive_query_native( $query_args, $loop );
				break;
			case 'post_type':
				$query_args = $this->fake_archive_query_post_type( $query_args, $loop );
				break;
			case 'taxonomy':
				$query_args = $this->fake_archive_query_taxonomy( $query_args, $loop );
				break;
		}
		return $query_args;
	}

	function fake_archive_query_native( $query_args, $loop ) {
		// 'home'|'search'|'author'|'year'|'month'|'day'
		switch ( $loop['name'] ) {
			case 'home':

				break;
			case 'search':
				$query_args['s']			= $loop['data']['s'];
				break;
			case 'author':
				$query_args['author_name']	= $loop['data']['author_name'];
				break;
			case 'year':
				$query_args['year']			= $loop['data']['year'];
				break;
			case 'month':
				$query_args['year']			= $loop['data']['year'];
				$query_args['monthnum']		= $loop['data']['monthnum'];
				break;
			case 'day':
				$query_args['year']			= $loop['data']['year'];
				$query_args['monthnum']		= $loop['data']['monthnum'];
				$query_args['day']			= $loop['data']['day'];
				break;
		}
		return $query_args;
	}

	function fake_archive_query_post_type( $query_args, $loop ) {
		$query_args['post_type'] = $loop['name'];
		return $query_args;
	}

	function fake_archive_query_taxonomy( $query_args, $loop ) {
		$query_args['tax_query'] = array(
			'relation' => 'AND',
			array(
				'taxonomy'			=> $loop['data']['taxonomy'],
				'field'				=> 'slug',
				'terms'				=> array( $loop['data']['term'] ),
				'operator'			=> 'IN',
				"include_children"	=> true
			)
		);
		return $query_args;
	}

	function fake_archive_before_set( $query ) {
		if ( $query->get( 'wpv_fake_archive_loop' ) ) {
			// Set the right query properties
			$loop = $query->get( 'wpv_fake_archive_loop' );
			switch ( $loop['type'] ) {
				case 'native':
					switch ( $loop['name'] ) {
						case 'home':
							$query->is_admin	= false;
							$query->is_archive	= false;
							$query->is_home		= true;
							break;
						case 'search':
							$query->is_admin	= false;
							$query->is_archive	= true;
							$query->is_search	= true;
							break;
						case 'author':
							$query->is_admin	= false;
							$query->is_archive	= true;
							$query->is_author	= true;
							break;
						case 'year':
							$query->is_admin	= false;
							$query->is_archive	= true;
							$query->is_date		= true;
							$query->is_year		= true;
							break;
						case 'month':
							$query->is_admin	= false;
							$query->is_archive	= true;
							$query->is_date		= true;
							$query->is_month	= true;
							break;
						case 'day':
							$query->is_admin	= false;
							$query->is_archive	= true;
							$query->is_date		= true;
							$query->is_day		= true;
							break;
					}
					break;
				case 'post_type':
					$query->is_admin				= false;
					$query->is_archive				= true;
					$query->is_post_type_archive	= true;
					break;
				case 'taxonomy':
					switch ( $loop['name'] ) {
						case 'category':
							$query->is_admin	= false;
							$query->is_archive	= true;
							$query->is_category	= true;
							$query->set( 'category_name', $loop['data']['term'] );
							break;
						case 'post_tag':
							$query->is_admin	= false;
							$query->is_archive	= true;
							$query->is_tag		= true;
							$query->set( 'tag', $loop['data']['term'] );
							break;
						default:
							$query->is_admin	= false;
							$query->is_archive	= true;
							$query->is_tax		= true;
							break;
					}
					break;
			}
			// Make this the main query
			global $wp_the_query, $wp_query;
			$wp_the_query = $query;
			$wp_query = $query;
		}
	}

	function wpv_get_archive_query_results() {

		$loop			= $_POST['loop'];// @todo sanitize $loop
		$page			= $_POST['page'];
		$sort			= isset( $_POST['sort'] ) ? $_POST['sort'] : array();
		$environment	= isset( $_POST['environment'] ) ? $_POST['environment'] : array();
		$search			= isset( $_POST['search'] ) ? $_POST['search'] : array();
		$search_keys	= array();
		$extra			= isset( $_POST['extra'] ) ? $_POST['extra'] : array();

		$_GET['wpv_view_count']	= sanitize_text_field( $_POST['view_number'] );

		$query_args	= $this->fake_archive_query( $loop );
		$query_args['paged'] = (int) $page;

		foreach ( $sort as $sort_key => $sort_value ) {
			if ( in_array( $sort_key, array( 'wpv_sort_orderby', 'wpv_sort_order', 'wpv_sort_orderby_as', 'wpv_sort_orderby_second', 'wpv_sort_order_second' ) ) ) {
				$_GET[ $sort_key ] = sanitize_text_field( $sort_value );
			}
		}

		foreach ( $environment as $environment_key => $environment_value ) {
			if (
				in_array( $environment_key, array( 'wpv_aux_current_post_id', 'wpv_aux_parent_post_id', 'wpv_aux_parent_term_id', 'wpv_aux_parent_user_id' ) )
				&& (int) $environment_value > 0
			) {
				$search_keys[] = $environment_key;
				$_GET[ $environment_key ] = (int) $environment_value;
				global $WP_Views;
				switch ( $environment_key ) {
					case 'wpv_aux_current_post_id':
						$top_post_id = (int) $environment_value;
						$top_post = get_post( $top_post_id );
						$WP_Views->top_current_page = $top_post;
						break;
					case 'wpv_aux_parent_post_id':
						global $post, $authordata, $id;
						$post_id = (int) $environment_value;
						$post = get_post( $post_id );
						$authordata = new WP_User( $post->post_author );
						$id = $post->ID;
						$WP_Views->current_page = array( $post );
						break;
					case 'wpv_aux_parent_term_id':
						$WP_Views->parent_taxonomy = (int) $environment_value;
						break;
					case 'wpv_aux_parent_user_id':
						$WP_Views->parent_user = (int) $environment_value;
						break;
				}
			}
		}

		if ( isset( $search['dps_general'] ) ) {
			$corrected_item = array();
			foreach ( $search['dps_general'] as $dps_pr_item ) {
				if (
					is_array( $dps_pr_item )
					&& isset( $dps_pr_item['name'] )
					&& isset( $dps_pr_item['value'] )
				) {
					if ( strlen( $dps_pr_item['name'] ) < 2 ) {
						$search_keys[] = $dps_pr_item['name'];
						$_GET[ $dps_pr_item['name'] ] = sanitize_text_field( wp_unslash( $dps_pr_item['value'] ) );
					} else {
						if ( strpos( $dps_pr_item['name'], '[]' ) === strlen( $dps_pr_item['name'] ) - 2 ) {
							$name = str_replace( '[]', '', $dps_pr_item['name'] );
							$search_keys[] = $name;
							if ( ! in_array( $name, $corrected_item ) ) {
								$corrected_item[] = $name;
								if ( isset( $_GET[ $name ] ) ) {
									unset( $_GET[ $name ] );
								}
							}
							if ( ! isset( $_GET[ $name ] ) ) {
								$_GET[ $name ] = array( sanitize_text_field( wp_unslash( $dps_pr_item['value'] ) ) );
							} else if ( is_array( $_GET[ $name ] ) ) {
								$_GET[ $name ][] = sanitize_text_field( wp_unslash( $dps_pr_item['value'] ) );
							}
						} else {
							$search_keys[] = $dps_pr_item['name'];
							$_GET[ $dps_pr_item['name'] ] = sanitize_text_field( wp_unslash( $dps_pr_item['value'] ) );
						}
					}
				}
			}
		}

		if ( isset( $search['dps_pr'] ) ) {
			foreach ( $search['dps_pr'] as $dps_pr_item ) {
				if (
					is_array( $dps_pr_item )
					&& isset( $dps_pr_item['name'] )
					&& isset( $dps_pr_item['value'] )
				) {
					if ( strlen( $dps_pr_item['name'] ) < 2 ) {
						if ( ! isset( $_GET[ $dps_pr_item['name'] ] ) ) {
							$search_keys[] = $dps_pr_item['name'];
							$_GET[ $dps_pr_item['name'] ] = sanitize_text_field( wp_unslash( $dps_pr_item['value'] ) );
						}
					} else {
						if ( strpos( $dps_pr_item['name'], '[]' ) === strlen( $dps_pr_item['name'] ) - 2 ) {
							$name = str_replace( '[]', '', $dps_pr_item['name'] );
							$search_keys[] = $name;
							if ( ! isset( $_GET[ $name ] ) ) {
								$_GET[ $name ] = array( sanitize_text_field( wp_unslash( $dps_pr_item['value'] ) ) );
							} else if ( is_array( $_GET[$name] ) ) {
								$_GET[ $name ][] = sanitize_text_field( wp_unslash( $dps_pr_item['value'] ) );
							}
						} else {
							if ( ! isset( $_GET[ $dps_pr_item['name'] ] ) ) {
								$search_keys[] = $dps_pr_item['name'];
								$_GET[ $dps_pr_item['name'] ] = sanitize_text_field( wp_unslash( $dps_pr_item['value'] ) );
							}
						}
					}
				}
			}
		}

		foreach ( $extra as $extra_key => $extra_value ) {
			if ( ! in_array( $extra_key, $search_keys ) ) {
				if ( ! isset( $_GET[ $extra_key ] ) ) { // Might be redundant with the check on $search_keys
					// @hack alert!! We can not avoid this :-(
					if ( strpos( $extra_value, '##URLARRAYVALHACK##' ) !== false ) {
						$_GET[ $extra_key ] = explode( '##URLARRAYVALHACK##', $extra_value );
						$_GET[ $extra_key ] = array_map( 'sanitize_text_field', $_GET[ $extra_key ] );
					} else {
						$_GET[ $extra_key ] = sanitize_text_field( $extra_value );
					}
				}
			}
		}

		if ( toolset_getpost( 'lang', false ) ) {
			do_action( 'wpml_switch_language', sanitize_text_field( toolset_getpost( 'lang', '' ) ) );
		}

		global $wp_the_query, $wp_query, $paged;
		$archive_query		= new WP_Query( $query_args );
		$wp_the_query		= $archive_query;
		$wp_query			= $archive_query;
		$paged				= $query_args['paged'];

		$this->initialize_archive_loop();
		if ( $this->loop_has_no_posts ) {
			// Reset everything if the loop has no posts.
			// Then the WPA will render with no posts.
			global $post;
			$this->post_count = 0;
			$this->query->post_count = 0;
			$wp_query->post_count = 0;
			$wp_query->posts = array();
			$this->query->posts = array();
			$post = null;
		}

		if ( $this->loop_has_no_posts ) {
			// Reset everything if the loop has no posts.
			// Then the WPA will render with no posts.
			$this->post_count = 0;
			$this->query->post_count = 0;
			$wp_query->post_count = 0;
			$wp_query->posts = array();
			$this->query->posts = array();
		}

		$this->in_the_loop = true;
		$data = array(
			'id'	=> $loop['id'],
			'full'	=> render_view( array( 'id' => $loop['id'] ) )
		);
		$this->in_the_loop = false;

		$data['form'] = $data['full'];

		$archive_settings			= apply_filters( 'wpv_filter_wpv_get_view_settings', array(), $loop['id'] );
		$pagination_permalinks		= apply_filters( 'wpv_filter_wpv_get_pagination_permalinks', array(), $archive_settings, $loop['id'] );

		if ( $paged == 1 ) {
			$pagination_permalink = $pagination_permalinks['first'];
		} else {
			$pagination_permalink = str_replace( 'WPV_PAGE_NUM', $paged, $pagination_permalinks['other'] );
		}

		// For parametric search URL history management
		$data['permalink']				= $pagination_permalink;
		// In theory, this is only used by parametric search, so we should always use the 'first' one above.
		$data['parametric_permalink']	= $pagination_permalink;

		if ( ! wpv_parametric_search_triggers_history( $loop['id'] ) ) {
			// When parametric search does not manage history, we need to clean the URL.
			$view_url_data					= get_view_allowed_url_parameters( $loop['id'] );
			$query_args_remove				= wp_list_pluck( $view_url_data, 'attribute' );
			foreach ( $query_args_remove as $query_args_remove_string ) {
				$query_args_remove[] = $query_args_remove_string . '[]';
			}
			$query_args_remove[]			= 'wpv_sort_orderby';
			$query_args_remove[]			= 'wpv_sort_order';
			$query_args_remove[]			= 'wpv_sort_orderby_as';
			$query_args_remove[]			= 'wpv_sort_orderby_second';
			$query_args_remove[]			= 'wpv_sort_order_second';
			$query_args_remove[]			= 'wpv_aux_current_post_id';
			$query_args_remove[]			= 'wpv_aux_parent_post_id';
			$query_args_remove[]			= 'wpv_aux_parent_term_id';
			$query_args_remove[]			= 'wpv_aux_parent_user_id';
			$query_args_remove[]			= 'wpv_view_count';
			$data['parametric_permalink']	= remove_query_arg(
				$query_args_remove,
				$pagination_permalink
			);
		}

		if ( did_action( 'wp_playlist_scripts' ) ) {
			// The View outcome has a playlist shortcode:
			// let's include the playlist templates in the response.
			ob_start();
			wp_underscore_playlist_templates();
			$data['playlist_templates'] = ob_get_clean();
		}

		wp_send_json_success( $data );
	}

	// Auxiliar methods

	function is_frontend() {
		if ( ! is_admin() ) {
			return true;
		} else if (
			defined( 'DOING_AJAX' )
			&& DOING_AJAX
			&& isset( $_REQUEST['action'] )
			&& $_REQUEST['action'] == 'wpv_get_archive_query_results'
		) {
			return true;
		} else {
			return false;
		}
	}

	/**
	* wpv_initialize_wordpress_archive_for_archive_loop
	*
	* Callback for the wpv_action_wpv_initialize_wordpress_archive_for_archive_loop action.
	*
	* This should be used to override the current archive loop, by:
	* - faking an archive query, based on the current archive settings and a given WPA ID.
	* - overriding the global queries with the generated one.
	* - initializing the current archive loop with the faked now-global query.
	*
	* This is mainly used by Layouts archive cells, since they are rendered after $wp_query is generated
	* and we might not have any WPA assigned to th current archive loop, or have another different one
	* and we do need to force the WPA stored in the Layouts cell settings.
	*
	* @since 2.1
	*/

	function wpv_initialize_wordpress_archive_for_archive_loop( $wpa_id ) {
		WPV_Cache::restart_cache();
		global $wp_the_query, $wp_query, $paged;
		$wpa_loop = array(
			'type'	=> $this->wpa_type,
			'name'	=> $this->wpa_name,
			'data'	=> $this->wpa_data,
			'id'	=> $wpa_id
		);
		$query_args				= $this->fake_archive_query( $wpa_loop );
		$query_args['paged']	= $paged;
		//$query_args['wpv_archive_loop_cell'] = true;
		$archive_query			= new WP_Query( $query_args );
		$wp_the_query			= $archive_query;
		$wp_query				= $archive_query;
		$this->initialize_archive_loop();
		if ( $this->loop_has_no_posts ) {
			// Reset everything if the loop has no posts.
			// Then the WPA will render with no posts.
			global $post;
			$this->post_count = 0;
			$this->query->post_count = 0;
			$wp_query->post_count = 0;
			$wp_query->posts = array();
			$this->query->posts = array();
			$post = null;
		}
	}

	public function early_pre_get_posts( $query ) {
		if ( is_wpv_wp_archive_assigned() ) {
			$query->set( 'ep_integrate', false );
		}
	}

	/**
	 * Returns the WPA assigned to a given term, if any.
	 *
	 * @param string $taxonomy_slug
	 * @param string $term_slug
	 *
	 * @return int
	 */
	public function get_archive_for_taxonomy_term( $taxonomy_slug, $term_slug ) {
		$current_language = apply_filters( 'wpml_current_language', '' );
		$default_language = apply_filters( 'wpml_default_language', '' );

		if ( $current_language !== $default_language ) {
			$term = get_term_by( 'slug', $term_slug, $taxonomy_slug );
			if ( false === $term ) {
				return 0;
			}
			$translated_term_id = apply_filters( 'wpml_object_id', $term->term_id, $term->taxonomy, true, $default_language );
			do_action( 'wpml_switch_language', $default_language );
			$original_term = get_term( $translated_term_id, $term->taxonomy );
			do_action( 'wpml_switch_language', $current_language );
			if ( false !== $original_term ) {
				$term_slug = $original_term->slug;
			}
		}

		$settings_term_key_template = self::SETTINGS_TAXONOMY_LOOP_OPTION;
		$settings_term_key = sprintf( $settings_term_key_template, $taxonomy_slug, $term_slug );

		if ( isset( $this->wpv_settings[ $settings_term_key ] ) && intval( $this->wpv_settings[ $settings_term_key ] ) > 0 ) {
			return intval( $this->wpv_settings[ $settings_term_key ] );
		}

		$settings_key_template = self::SETTINGS_TAXONOMY_LOOP;
		$settings_key = sprintf( $settings_key_template, $taxonomy_slug );

		if ( isset( $this->wpv_settings[ $settings_key ] ) && intval( $this->wpv_settings[ $settings_key ] ) > 0 ) {
			return intval( $this->wpv_settings[ $settings_key ] );
		}
		return 0;
	}

	/**
	 * Returns an array indexed by Archive ID's, and containing an array of term slugs associated to the archive.
	 *
	 * @param string $taxonomy_slug
	 *
	 * @return string[][]
	 */
	private function get_archive_settings_for_taxonomy_terms( $taxonomy_slug ) {
		$pattern_template = self::SETTINGS_TAXONOMY_LOOP_OPTION_REGEXP_TEMPLATE;
		$settings_term_options_pattern = sprintf( $pattern_template, $taxonomy_slug );
		$settings_terms = $this->wpv_settings->preg_key( $settings_term_options_pattern );
		$selected_terms = [];

		foreach ( $settings_terms as $settings_term_key ) {
			$term_matches = [];
			preg_match( $settings_term_options_pattern, $settings_term_key, $term_matches );
			if ( count( $term_matches ) > 0 ) {
				$wpa_id = intval( $this->wpv_settings->get( $settings_term_key ) );
				$selected_terms[ $wpa_id ][] = $term_matches[1];
			}
		}

		return $selected_terms;
	}

	/**
	 * Dynamically loading this instance, as at construct time the class is not yet loaded.
	 *
	 * @return Toolset_Post_Type_Repository
	 */
	private function get_post_type_repository() {
		if ( null === $this->post_type_repository ) {
			$this->post_type_repository = Toolset_Post_Type_Repository::get_instance();
		}
		return $this->post_type_repository;
	}
}


global $WPV_view_archive_loop;
$WPV_view_archive_loop = new WPV_WordPress_Archive_Frontend;

Page Not Found
Parece que el enlace que apuntaba aquí no sirve. ¿Quieres probar con una búsqueda?
¡Hola!